// Copyright (c) 2010, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// ---
// Author: Jeffrey Junfeng Pan (panjunfeng@gmail.com)

#ifndef FP_GROWTH_NODE_H_
#define FP_GROWTH_NODE_H_

#include <unordered_map>
#include <string>
#include <vector>

#include "base.h"
#include "common/macros.h"
#include "common/scoped_ptr.h"

// Node is a basic class used for constructing
// frequent pattern tree as well as frequent pattern itemset mining.

namespace frequent_pattern_mining {

// ------------------------------------------------------------
//                      Declaration
// ------------------------------------------------------------

class Node {
 public:

  // Constructor, initialized with the value of item index.
  inline explicit Node(int index);

  // Destructor.
  inline ~Node();

  // Get the item index stored in the node.
  inline int index() const;

  // Set the item index in the node.
  inline void set_index(int index);

  // Get the item frequency stored in the node.
  inline const int frequency() const;

  // Set the item frequency in the node.
  inline void set_frequency(int frequency);

  // Get the pointer to the parent node.
  inline Node* parent() const;

  // Set the pointer to the parent node.
  inline void set_parent(Node* parent);

  // Get the vector of children nodes.
  inline const vector<Node*>& children() const;

  // Add a child to the children vector of the node.
  inline void add_child(Node* new_child);

  // Get the link to next node in a header table.
  inline Node* header_next() const;

  // Set the link to the next node in a header table.
  inline void set_header_next(Node* header_next);

 private:

  // Pointer to the node's parent
  Node* parent_;

  // Pointer to the next node in the header table.
  // In a frequent pattern tree, multiple nodes
  // may have the same index (the same item).
  // Those nodes are linked together.
  Node* header_next_;

  // All the points to the children nodes.
  vector<Node*> children_;

  // The item index.
  int index_;

  // The item frequency.
  int frequency_;

  DISALLOW_EVIL_CONSTRUCTORS(Node);
};

// ------------------------------------------------------------
//                      Definition
// ------------------------------------------------------------

// Constructor, initialized with the value of item index.
Node::Node(int index)
  : parent_(NULL),
    header_next_(NULL),
    index_(index),
    frequency_(0) {
}

// Destructor.
Node::~Node() {
  for (int i = 0; i < children_.size(); ++i) {
    if (children_[i] != NULL) {
      delete children_[i];
      children_[i] = NULL;
    }
  }
}

// Get the item index stored in the node.
int Node::index() const {
  return index_;
}

// Set the item index in the node.
void Node::set_index(int index) {
  index_ = index;
}

// Get the item frequency stored in the node.
const int Node::frequency() const {
  return frequency_;
}

// Set the item frequency in the node.
void Node::set_frequency(int frequency) {
  frequency_ = frequency;
}

// Get the pointer to the parent node.
Node* Node::parent() const {
  return parent_;
}

// Set the pointer to the parent node.
void Node::set_parent(Node* parent) {
  parent_ = parent;
}

// Get the vector of children nodes.
const vector<Node*>& Node::children() const {
  return children_;
}

// Add a child to the children vector of the node.
void Node::add_child(Node* new_child) {
  children_.push_back(new_child);
}

// Get the link to the next node in a header table.
Node* Node::header_next() const {
  return header_next_;
}

// Set the link to the next node in a header table.
void Node::set_header_next(Node* header_next) {
  header_next_ = header_next;
}

}  // namespace frequent_pattern_mining

#endif  // FP_GROWTH_NODE_H_
